package eval

import (
	"showen7/inter"
)

func RegisterBuiltinProcedures(globalEnv *inter.Environment) {
	// Type predicates
	globalEnv.Set("boolean?", &inter.Builtin{Fn: IsBooleanProc})
	globalEnv.Set("symbol?", &inter.Builtin{Fn: IsSymbolProc})
	globalEnv.Set("number?", &inter.Builtin{Fn: IsNumberProc})
	globalEnv.Set("integer?", &inter.Builtin{Fn: IsIntegerProc})
	globalEnv.Set("rational?", &inter.Builtin{Fn: IsRationalProc})
	globalEnv.Set("real?", &inter.Builtin{Fn: IsRealProc})
	globalEnv.Set("complex?", &inter.Builtin{Fn: IsComplexProc})
	globalEnv.Set("char?", &inter.Builtin{Fn: IsCharProc})
	globalEnv.Set("string?", &inter.Builtin{Fn: IsStringProc})
	globalEnv.Set("procedure?", &inter.Builtin{Fn: IsProcedureProc})
	globalEnv.Set("pair?", &inter.Builtin{Fn: IsPairProc})

	// Equivalence predicates
	globalEnv.Set("eq?", &inter.Builtin{Fn: Eq})
	globalEnv.Set("eqv?", &inter.Builtin{Fn: Eqv})
	globalEnv.Set("equal?", &inter.Builtin{Fn: Equal})

	// Comparison procedures
	globalEnv.Set("<", &inter.Builtin{Fn: lessThan})
	globalEnv.Set("<=", &inter.Builtin{Fn: lessThanOrEqual})
	globalEnv.Set("=", &inter.Builtin{Fn: equal})
	globalEnv.Set(">=", &inter.Builtin{Fn: greaterThanOrEqual})
	globalEnv.Set(">", &inter.Builtin{Fn: greaterThan})

	// Arithmetic procedures
	globalEnv.Set("+", &inter.Builtin{Fn: Add})
	globalEnv.Set("-", &inter.Builtin{Fn: Subtract})
	globalEnv.Set("*", &inter.Builtin{Fn: Multiply})
	globalEnv.Set("/", &inter.Builtin{Fn: Divide})

	// Register pair operations
	globalEnv.Set("cons", &inter.Builtin{Fn: Cons})
	globalEnv.Set("car", &inter.Builtin{Fn: Car})
	globalEnv.Set("cdr", &inter.Builtin{Fn: Cdr})
	//globalEnv.Set("list", &inter.Builtin{Fn: List})
	globalEnv.Set("set-car!", &inter.Builtin{Fn: SetCar})
	globalEnv.Set("set-cdr!", &inter.Builtin{Fn: SetCdr})

	// Register cXr functions (up to 4 levels deep)
	globalEnv.Set("caar", &inter.Builtin{Fn: Caar})
	globalEnv.Set("cadr", &inter.Builtin{Fn: Cadr})
	globalEnv.Set("cdar", &inter.Builtin{Fn: Cdar})
	globalEnv.Set("cddr", &inter.Builtin{Fn: Cddr})
}
